package com.ym.medical.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ym.common.constant.UserDetails;
import com.ym.common.enums.LoginMethodEnum;
import com.ym.common.utils.SourceFileUtil;
import com.ym.core.config.AuthSystemApi;
import com.ym.core.config.ConfigCenterProperties;
import com.ym.core.config.MenuTreeUtil;
import com.ym.core.domain.APIResponse;
import com.ym.core.exception.BusinessException;
import com.ym.core.exception.SysLoginException;
import com.ym.core.exception.SysLoginHeaderException;
import com.ym.core.shiro.ShiroUtil;
import com.ym.core.shiro.service.SysLoginService;
import com.ym.core.shiro.token.SysToken;
import com.ym.medical.domain.entity.SysUserEntity;
import com.ym.medical.domain.vo.Node;
import com.ym.medical.service.ISysUserSV;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统用户表Service业务层处理
 *
 * @author ym
 * @date 2020-08-17
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class SysUserSVImpl implements ISysUserSV, SysLoginService {

	@Autowired
	private ConfigCenterProperties configCenterProperties;

	@Autowired
	private RestTemplate restTemplate;

	/**
	 * 系统登录跨服务调用实现类
	 *
	 * @param wxToken
	 * @return
	 */
	@Override
	public UserDetails loginByUsernamePassword(SysToken wxToken) {
		AuthSystemApi mbsConnectUrl = configCenterProperties.getAuthSystemApi();
		String loginUrl = mbsConnectUrl.getLoginUrl();
		Map<String, Object> params = new HashMap<>();
		params.put("code", wxToken.getUsername());
		params.put("pwd", wxToken.getPassword());
		//菜单code
		params.put("menuCode", "ymInquiryNode");
		HttpHeaders headers = null;
		try {
			String appKey = SourceFileUtil.source("authKey.txt");
			headers = SourceFileUtil.restTemplateHeader(appKey);
		} catch (Exception e) {
			log.info("登录组装header 失败:{}", e.getMessage());
			throw new SysLoginHeaderException();
		}
		HttpEntity httpEntity = new HttpEntity<>(params, headers);
		String execute = restTemplate.postForObject(loginUrl, httpEntity, String.class);
		JSONObject jsonObject = JSONObject.parseObject(execute);
		if ("1".equals(jsonObject.getString("code"))) {
			JSONObject data = jsonObject.getJSONObject("data");
			JSONArray array = data.getJSONArray("menuNodeList");
			List<Node> nodes = array.toJavaList(Node.class);
			Long parentId = null;
			for (Node node : nodes) {
				if (node.getCode() != null && "ymInquiryNode".equals(node.getCode())) {
					parentId = node.getId();
				}

			}
			MenuTreeUtil menuTreeUtil = new MenuTreeUtil();
			List<Object> sysMenu = menuTreeUtil.getMenuList(nodes, parentId);
			ShiroUtil.getSession().setAttribute("menuList", sysMenu);
			SysUserEntity userDetails = data.getJSONObject("user").toJavaObject(SysUserEntity.class);
			// 登录方式确定
			userDetails.setLoginMethod(LoginMethodEnum.ACC_PWD);
			//账户冻结
			JSONObject state = (JSONObject) JSONObject.parse(userDetails.state());
			if ("02".equals(state.getString("key"))) {
				throw new DisabledAccountException();
			}
			return userDetails;
		} else {
			throw new SysLoginException();
		}
	}

	/**
	 * 手机号查询系统用户
	 *
	 * @param phone
	 * @return
	 */
	@Override
	public SysUserEntity sysUser(String phone) {
		Map<String, Object> param = new HashMap<>();
		param.put("mobile", phone);
		String url = configCenterProperties.getAuthSystemApi()
				.getSysUserByPhone();

		String appKey = null;
		HttpHeaders headers = null;
		try {
			appKey = SourceFileUtil.source("authKey.txt");
			headers = SourceFileUtil.restTemplateHeader(appKey);
		} catch (Exception e) {
			log.info("跨系统异常:{}", e.getMessage());
			throw new BusinessException("跨系统异常");
		}
		HttpEntity<String> entity = new HttpEntity<>(null, headers);
		ResponseEntity<APIResponse> responseEntity = restTemplate
				.exchange(url + "?mobile={mobile}", HttpMethod.GET, entity, APIResponse.class, param);
		JSONObject jsonObject = (JSONObject) responseEntity.getBody().getData();
		return JSONObject.parseObject(jsonObject.toJSONString(), SysUserEntity.class);
	}

	@Override
	public Boolean existByPhone(String phone) {
		SysUserEntity sysUserEntity = sysUser(phone);
		return sysUserEntity != null;
	}

	@Override
	public APIResponse getOrgCodes(String code) throws Exception {
		String url = configCenterProperties.getAuthSystemApi().getGetSysOrgName();
		if (StringUtils.isNotBlank(code)) {
			url = url + "?code=" + code;
		}
		String appKey = SourceFileUtil.source("authKey.txt");
		HttpHeaders headers = SourceFileUtil.restTemplateHeader(appKey);
		HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
		Map<String, Object> param = new HashMap<>();
		param.put("code", code);
		ResponseEntity<APIResponse> resEntity =
				restTemplate.exchange(url, HttpMethod.GET, requestEntity, APIResponse.class, param);
		APIResponse response = resEntity.getBody();
		return response;
	}

	@Override
	public String selectUsernameById(Long id) {
		try {
			String url = configCenterProperties.getAuthSystemApi().getGetUserNameUrl();
			String appKey = SourceFileUtil.source("authKey.txt");
			HttpHeaders headers = SourceFileUtil.restTemplateHeader(appKey);
			HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
			Map<String, Object> param = new HashMap<>();
			param.put("id", id);
			ResponseEntity<APIResponse> resEntity =
					restTemplate.exchange(url + "?id={id}", HttpMethod.GET, requestEntity, APIResponse.class, param);
			APIResponse response = resEntity.getBody();
			if ("1".equals(response.getCode())) {
				Map<String, String> user = (Map) response.getData();
				String userName = (String) user.get("code");
				return userName;
			}
		} catch (Exception e) {
			return null;
		}
		return null;
	}
}
